﻿using System.Diagnostics;
using Windows.Devices.Input;
using Windows.Foundation;
using Windows.UI.Core;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using XamlInspector.Foundation;

namespace XamlInspector.Presentation.Controls
{
    public class OverlayWindow : ContentControl
    {
        private Popup _popup = new Popup();

        public OverlayWindow()
        {
            DefaultStyleKey = typeof(OverlayWindow);
            //Window.Current.CoreWindow.PointerCursor = new CoreCursor(CoreCursorType.SizeAll, 1);
        }

        public int Left
        {
            get { return (int)GetValue(LeftProperty); }
            set { SetValue(LeftProperty, value); }
        }

        public static readonly DependencyProperty LeftProperty =
            DependencyProperty.Register("Left", typeof(int), typeof(OverlayWindow), new PropertyMetadata(0));

        public int Top
        {
            get { return (int)GetValue(TopProperty); }
            set { SetValue(TopProperty, value); }
        }

        public static readonly DependencyProperty TopProperty =
            DependencyProperty.Register("Top", typeof(int), typeof(OverlayWindow), new PropertyMetadata(0));

        protected override void OnApplyTemplate()
        {
            var title = (UIElement)GetTemplateChild("titleBar");
            new MoveHandler(title, this, _popup);

            var leftResizeArea = (UIElement)GetTemplateChild("leftResizeArea");
            new ResizeHandler(leftResizeArea, this, _popup, CoreCursors.SizeWestEast, true, true);

            var rightResizeArea = (UIElement)GetTemplateChild("rightResizeArea");
            new ResizeHandler(rightResizeArea, this, _popup, CoreCursors.SizeWestEast, true, false);

            var bottomResizeArea = (UIElement)GetTemplateChild("bottomResizeArea");
            new ResizeHandler(bottomResizeArea, this, _popup, CoreCursors.SizeNorthSouth, false, false);

        }

        public void Show()
        {
            _popup = new Popup
                     {
                         VerticalOffset = Top,
                         HorizontalOffset = Left,
                         IsOpen = true,
                         Child = this
                     };

            _popup.SetBinding(HeightProperty, new Binding { Source = this, Path = new PropertyPath("ActualHeight") });
            _popup.SetBinding(WidthProperty, new Binding { Source = this, Path = new PropertyPath("ActualWidth") });
        }

        internal class ResizeHandler
        {
            private readonly Popup _popup;
            private Point _offset;
            private Point _startPoint;
            private double _startWidth;
            private double _startHeight;
            private readonly CoreCursor _cursor;
            private bool _isMoving;

            public ResizeHandler(UIElement element, OverlayWindow host, Popup popup, CoreCursor cursor, bool leftRight, bool left)
            {
                _popup = popup;
                _cursor = cursor;
                element.PointerEntered += (s, e) => { Window.Current.CoreWindow.PointerCursor = _cursor; };
                element.PointerExited += (s, e) => { Window.Current.CoreWindow.PointerCursor = CoreCursors.Arrow; };
                element.PointerPressed += (s, e) =>
                                          {
                                              _startPoint = Window.Current.CoreWindow.PointerPosition;
                                              _offset = new Point(_startPoint.X - _popup.HorizontalOffset, _startPoint.Y - _popup.VerticalOffset);
                                              _startWidth = host.ActualWidth;
                                              _startHeight = host.ActualHeight;
                                              element.CapturePointer(e.Pointer);
                                              _isMoving = true;
                                          };
                element.PointerReleased += (s, e) =>
                                           {
                                               element.ReleasePointerCaptures();
                                               _isMoving = false;
                                           };
                host.PointerMoved += (s, e) =>
                                     {
                                         if (_isMoving)
                                         {
                                             var pos = Window.Current.CoreWindow.PointerPosition;

                                             if (leftRight)
                                             {
                                                 if (left)
                                                 {
                                                     var diff = (pos.X - _offset.X) - _popup.HorizontalOffset;
                                                     _popup.HorizontalOffset = pos.X - _offset.X;
                                                     host.Width = host.ActualWidth - diff;
                                                 }
                                                 else
                                                 {
                                                     var diff = _startPoint.X - pos.X;
                                                     host.Width = _startWidth - diff;
                                                 }
                                             }
                                             else
                                             {
                                                 var diff = _startPoint.Y - pos.Y;
                                                 host.Height = _startHeight - diff;
                                             }
                                         }
                                     };
            }
        }

        internal class MoveHandler
        {
            private readonly Popup _popup;
            private Point _offset;
            private bool _isMoving;

            public MoveHandler(UIElement element, UIElement host, Popup popup)
            {
                _popup = popup;
                element.PointerEntered += (s, e) => { Window.Current.CoreWindow.PointerCursor = CoreCursors.SizeAll; };
                element.PointerExited += (s, e) => { Window.Current.CoreWindow.PointerCursor = CoreCursors.Arrow; };
                element.PointerPressed += (s, e) =>
                                          {
                                              var pos = Window.Current.CoreWindow.PointerPosition;
                                              _offset = new Point(pos.X - _popup.HorizontalOffset, pos.Y - _popup.VerticalOffset);
                                              element.CapturePointer(e.Pointer);
                                              _isMoving = true;
                                          };
                element.PointerReleased += (s, e) =>
                                           {
                                               element.ReleasePointerCaptures();
                                               _isMoving = false;
                                           };
                host.PointerMoved += (s, e) =>
                                        {
                                            if (_isMoving)
                                            {
                                                var pos = Window.Current.CoreWindow.PointerPosition;
                                                _popup.HorizontalOffset = pos.X - _offset.X;
                                                _popup.VerticalOffset = pos.Y - _offset.Y;
                                            }
                                        };

            }
        }

    }
}
